1.URL的一般格式为(带方括号[]的为可选项):
protocol :// hostname[:port] / path / [;parameters][?query]#fragmen
urllib是一个包,里边共有四个模块;
在Python社区,有一个比Python”亲儿子”urllib还好用的 HTTP库——Requests。Requests是个开源项目,目前正在热火朝天地不断进化中,因此可以在Github上获取该项目(https://github.com/requests/requests)的源代码
网页解析利器BeautifulSoup4(BS4)
2.编码
美国ASCII、中国GB2312、日本Shift_JIS、韩国Euc-kr……..
Unicode组织:创建一个足够大的编码,将所有国家的编码都加进来,执行统一标准即Unicode编码。
的UTF-8编码就是Unicode的一种实现方式,它是可变长编码。当文本是ASCII编码的字符时,它用1字节存放;而 当文本是其他Unicode字符时,它将按一定算法转换,每个字符使用1~3 字节存放,这样便实现了有效节省空间的目的。
3.爬取网易云歌曲《丑八怪》热评
p14_5.py
import requests
import json
def get_hot_comments(res):
comments_json = json.loads(res.text)
hot_comments = comments_json['hotComments']
with open('hot_comments.txt', 'w', encoding='utf-8') as file:
for each in hot_comments:
file.write(each['user']['nickname'] + ':\n\n')
file.write(each['content'] + '\n')
file.write("---------------------------------------\n")
def get_comments(url):
# 给它传个 referer 以免服务器疑神疑鬼的@_@
# 当然,你这有时间的话将headers头部填写完整,那样妥妥会更好一些......
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36',
'referer': 'http://music.163.com/'
}
params = "EuIF/+GM1OWmp2iaIwbVdYDaqODiubPSBToe5EdNp6LHTLf+aID/dWGU6bHWXS0jD9pPa/oY67TOwiicLygJ+BhMkOX/J1tZMhq45dcUIr6fLuoHOECYrOU6ySwH4CjxxdbW3lpVmksGEdlxbZevVPkTPkwvjNLDZHK238OuNCy0Csma04SXfoVM3iLhaFBT"
encSecKey = "db26c32e0cd08a11930639deadefda2783c81034be6445ca8f4fbedd346e1f9567375083aeb1a85e6ad6d9ae4532a49752c2169db8bcc04d38a79f9bed7facea42ee23f1b33538c34f82741318d9b4b846663b53b0b808dd0499dccfbc6c61fbf180c6fb24b1c2dd3c2c450ce09917d74be9424dab836fd2e671988ffbc6ae1b"
data = {
"params": params,
"encSecKey": encSecKey
}
name_id = url.split('=')[1]
target_url = "http://music.163.com/weapi/v1/resource/comments/R_SO_4_{}?csrf_token=".format(name_id)
res = requests.post(target_url, headers=headers, data=data)
return res
def main():
url = input("请输入链接地址:")
res = get_comments(url)
get_hot_comments(res)
if __name__ == "__main__":
main()
#链接地址:http://music.163.com/#/song?id=27808044
4.正则表达式
re模块,如re.search()
通配符:大家都知道通配符,就是和?,用它来表示任何字符。例如想找到 所有Word类型的文件时,就输入.docx,对不对? 正则表达式也有所谓的通配符,在这里是用一个点号(.)来表 示,它可以匹配除了换行符之外的任何字符。
反斜杠:在正则表达式中,反斜杠可以剥夺元字符的特殊能力。元字符就是拥有特殊能力的符号,像刚才的点号(.)就是一个元字符。同时,反斜杠还可以使得普通字符拥有特殊能力。 举个例子,比如想匹配数字,那么可以使用反斜杠加上小写字母 d(\d).
#匹配一段IP地址
import re
re.search(r'\d\d\d\.\d\d\d\.\d\d\d\.\d\d\d', 'other192.168.111.253otkljkhr')
#
#改进版本
>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])', 'other192.168.1.1other')
#
字符类:使用中括号将任 何内容包起来就是一个字符类;它的含义是只要匹配这个字符类中的任 何字符,结果就算作匹配
重复匹配
特殊符号及用法:正则表达式的强大之处在于特殊符号的应用,特殊符号定义了字符集合、子组匹配、模式重复次数。正是这些特殊符号使得一个正则表达式可以匹配一个复杂的规则,而不仅仅只是一个字符串。
表15-1 Python 3正则表达式特殊符号及用法
表15-2 由字符’\’和另一个字符组成的特殊含义
表15-3 Python支持的所有扩展语法
元字符
. ^ $ * + ? { } [ ] \ | ( )
>>> re.search(r"(FishC)\060", "FishCFishC0")
>>> # 注:八进制60对应的ASCII码是数字0
>>> re.search(r"\141FishC", "aFishCFishC")
>>> # 注:八进制141对应的ASCII码是小写字母a
• 星号(*)相当于{0,}。
• 加号(+)相当于{1,}。
• 问号(?)相当于{0,1}。
贪婪和非贪婪:是正则表达式默认是启用贪 婪的匹配方式。什么是贪婪的匹配方式?就是说,只要在符合的条件 下,它会尽量多地去匹配。
反斜杠+普通字母=特殊含义
编译正则表达式
实用的方法
group()
re.search()
start()、end()和span()分别返回匹配的开始位置、结束位置和匹配的范围
findall()
finditer()
sub()
5.Scrapy爬虫框架
“西瓜 皮”(Scrapy)。因为Scrapy是Python开发的一个快速、高层次的屏幕抓取和Web抓取框架,用于抓取Web站点并从页面中提取结构化的数据。 Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
conda install -c conda-forge scrapy
Scrapy中的数据流是由中间的执行引擎控制的,其过程大致如下。
(1)从Spiders中获取第一个需要爬取的URL。
(2)使用Scheduler调度Requests,并向Scheduler请求下一个要爬取 的URL。
(3)Scheduler返回下一个要爬取的URL给执行引擎。
(4)执行引擎将URL通过Downloader Middlewares转发给 Downloader。
(5)一旦页面下载完毕,下载器生成一个该页面的Responses,并 将其通过Downloader Middlewares发送给执行引擎。
(6)引擎从Downloader中接收到Responses并通过Spider Middlewares发送给Spiders处理。 (7)Spiders处理Responses并返回爬取到的Items及新的Requests给 执行引擎。
(8)执行引擎将爬取到的Items给Item Pipeline,然后将Requests给 Scheduler。
(9)从第一步开始重复这个流程,直到Scheduler中没有更多的 URL。
这就是框架的好处,分工细致且井然有序。自己编写爬虫就像小作 坊制作,虽然可以针对性地开发,但相对来说效率偏低且容易出错;而使用爬虫框架则好比是大工厂的流水线加工,只要模具做得好,那么产出率是相当惊人的。
下面代码用于简单地爬取固定两个网页
import scrapy
#
#
class QuotesSpider(scrapy.Spider):
name = "quotes"
#
def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
#
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
#
def parse(self, response):
page = response.url.split("/")[-2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('Saved file %s' % filename)
#下面代码用于递归地爬取网站的相关内容
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('span small::text').extract_first(),
'tags': quote.css('div.tags a.tag::text').extract(),
}
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback=self.parse)
在Anaconda Prompt内,项目根目录tutorial下运行以下命令
scrapy crawl quotes
Original: https://blog.csdn.net/weixin_45663386/article/details/125811530
Author: 不成为hacker不改名
Title: python网络爬虫、正则表达式、Scrapy框架实例
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/790465/
转载文章受原作者版权保护。转载请注明原作者出处!