数据采集作业1
数据采集作业一
gitee链接:https://gitee.com/wangzm7511/shu-ju/tree/master/作业1
作业报告
作业①:上海大学排名信息爬取
1.1 作业代码与运行结果
作业代码
# 主要代码
url = "http://www.shanghairanking.cn/rankings/bcur/2020"
# 模拟浏览器请求头,防止被拒绝访问
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
}
# 发送请求获取页面内容
response = requests.get(url, headers=headers)
response.encoding = 'utf-8'
# 解析网页内容
soup = BeautifulSoup(response.text, 'html.parser')
# 查找排名表格
ranking_table = soup.find('table')
rows = ranking_table.find_all('tr')[1:] # 跳过表头
# 存储爬取的数据
data = []
for row in rows:
cols = row.find_all('td')
rank = cols[0].get_text(strip=True)
name = cols[1].get_text(strip=True)
province = cols[2].get_text(strip=True)
type_ = cols[3].get_text(strip=True)
score = cols[4].get_text(strip=True)
data.append([rank, name, province, type_, score])
# 创建DataFrame并输出
columns = ["排名", "学校名称", "省市", "学校类型", "总分"]
df = pd.DataFrame(data, columns=columns)
print(df)
运行结果
1.2 作业心得
在完成作业①的过程中,我学习了如何使用Python的requests
库发送HTTP请求,并结合BeautifulSoup
库解析HTML内容。通过分析目标网页的结构,我掌握了如何定位并提取所需的数据。
遇到的挑战:
-
动态加载内容:部分网站的数据是通过JavaScript动态加载的,这意味着直接使用
requests
获取的HTML内容中可能不包含实际的数据表格。为了应对这种情况,我尝试使用了更精确的选择器,并根据页面实际情况调整了解析逻辑。 -
反爬虫机制:目标网站可能有反爬虫措施,例如检测频繁请求或限制IP访问。为了减少被封禁的风险,我在请求头中添加了
User-Agent
,模拟常见浏览器的访问行为。 -
数据清洗:在提取学校类型时,需要去除多余的标识(如“双一流/985/211”),这需要对字符串进行分割和处理,确保最终输出的数据简洁且符合要求。
收获与体会:
通过此次作业,我深入理解了网页爬取的基本流程,包括发送请求、解析HTML、提取数据以及处理异常情况。同时,我也意识到了实际应用中可能遇到的各种问题,如动态内容加载和反爬虫机制,并学习了相应的应对策略。
作业②:某商城“书包”商品比价爬虫
2.1 作业代码与运行结果
作业代码
def crawl_jd_bookbags(cookies):
url = 'https://search.jd.com/Search?keyword=书包&enc=utf-8'
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15'
}
# 使用提供的cookies
session = requests.Session()
session.cookies.update(cookies)
response = session.get(url, headers=headers)
html_content = response.text
name_pattern = re.compile(r'<div class="p-name p-name-type-2">.*?<em>(.*?)</em>.*?</div>', re.S)
price_pattern = re.compile(r'<i data-price=".*?">(.*?)</i>', re.S)
product_names = name_pattern.findall(html_content)
product_prices = price_pattern.findall(html_content)
items = list(zip(product_names, product_prices))[:60]
for name, price in items:
name_clean = re.sub('<.*?>', '', name).strip()
print(f"商品名称: {name_clean}, 价格: {price}")
if __name__ == "__main__":
cookies = {
我的cookies
}
crawl_jd_bookbags(cookies)
运行结果
2.2 作业心得
完成作业②使我深入了解了如何在电商平台上进行商品比价爬虫的设计与实现。尽管选择了淘宝作为示例,但实际操作中发现,电商平台对爬虫有较强的反制措施,尤其是通过JavaScript动态加载内容,这对使用requests
和re
库的爬虫提出了挑战。
遇到的挑战:
-
复杂的页面结构:电商平台的页面结构复杂且频繁变化,需要不断调整爬虫的解析逻辑和正则表达式,以确保能够准确提取所需的数据。
-
反爬虫机制:由于京东具有一定的反爬机制,不允许匿名用户直接登录并爬取网页内容,故要通过设置 cookies 来让京东识别你,通过以下步骤实现。在访问京东网页时,浏览器会自动发送 cookies,而通过模拟这些 cookies,可以让京东识别为已登录的账号
收获与体会:
通过此次作业,我不仅巩固了使用requests
和re
库进行网页数据抓取的基本技能,还学习了如何应对实际项目中常见的动态内容和反爬虫机制。此外,我也认识到在复杂的电商平台上进行数据抓取时,可能需要结合多种工具和方法,如Selenium、Scrapy等,以实现更高效和稳定的爬虫。
这次作业让我意识到,爬虫开发不仅仅是编写代码,还需要深入理解目标网站的结构和行为,以及灵活应对各种技术挑战。这对于未来从事数据采集和分析工作具有重要的指导意义。
作业③:下载网页中的所有JPEG和JPG文件
3.1 作业代码与运行结果
作业代码
lock = threading.Lock()
def create_save_dir(keyword, save_dir):
save_path = os.path.join(save_dir, keyword)
if not os.path.exists(save_path):
os.makedirs(save_path)
return save_path
def download_image(img_url, image_count, save_path, headers):
if img_url.startswith('//'):
img_url = 'https:' + img_url
try:
img_data = requests.get(img_url, headers=headers).content
with open(f'{save_path}/{image_count}.jpg', 'wb') as f:
f.write(img_data)
with lock:
print(f'已下载第 {image_count} 张图片')
except Exception as e:
with lock:
print(f'图片下载失败: {e}')
def process_page(page_num, image_limit, image_count, save_path, headers):
url = f'https://search.jd.com/Search?keyword=音响&enc=utf-8&page={page_num * 2 - 1}'
response = requests.get(url, headers=headers)
html_content = response.text
image_urls = re.findall(r'data-lazy-img="(.*?)"', html_content)
for img_url in image_urls:
if image_count[0] >= image_limit:
break
with lock:
image_count[0] += 1
download_image(img_url, image_count[0], save_path, headers)
def crawl_images(keyword, image_limit=105, start_page=5, save_dir='Pictures'):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15',
'Cookie': 我的登录后的cookies
}
save_path = create_save_dir(keyword, save_dir)
image_count = [0] # 使用列表来共享变量
page = start_page
with ThreadPoolExecutor(max_workers=5) as executor:
while image_count[0] < image_limit:
executor.submit(process_page, page, image_limit, image_count, save_path, headers)
page += 1
if __name__ == '__main__':
crawl_images('音响', 105, start_page=5, save_dir='Pictures')
运行结果
3.2 作业心得
通过完成作业③,我掌握了如何使用Python自动化下载网页中的图片。这不仅涉及到基本的网页爬取,还包括文件操作和异常处理等多方面的知识。
遇到的挑战:
-
相对URL处理:网页中的图片链接可能是相对路径,需使用
urllib.parse.urljoin
将其转换为绝对URL,以确保能够正确下载图片。 -
图片命名冲突:部分图片URL可能不包含文件名或存在重复的文件名。这需要在保存图片时进行处理,如为图片命名添加索引或使用唯一标识符。
-
异常处理:在下载过程中,可能会遇到各种异常情况,如图片链接失效、网络问题等。需要通过异常处理机制,确保程序的健壮性,并能够继续下载其他图片。
收获与体会:
这次作业让我深入理解了如何结合使用requests
和BeautifulSoup
库进行数据抓取,并通过os
和urllib
库进行文件操作和URL处理。特别是在处理网页中的图片下载时,需要考虑多种可能的情况,如相对路径、缺失文件名和网络异常等,这极大地提升了我对实际项目中常见问题的应对能力。
此外,我也学习到了如何组织和管理下载的文件,通过创建专门的文件夹来存储图片,保持了文件系统的整洁。这对于未来需要批量下载和管理大量文件的项目具有重要的参考价值,为了提高下载效率,使用多线程或异步编程,实现并发下载。
总结
通过完成这三个作业,我不仅提升了Python编程技能,尤其是在网页爬取和数据处理方面,还深入理解了实际应用中可能遇到的各种技术挑战和解决方案。这些经验将为我未来的学习和项目开发奠定坚实的基础。